package org.goldenport.g3.sample

import org.goldenport.util.QSymbol
import org.goldenport.g3._
import org.goldenport.g3.adapters._
import org.goldenport.g3.messages._
import org.goldenport.g3.messages.entity._
import BookEntitySpace._

/**
 * @since   Aug. 19, 2010
 * @version Sep.  5, 2010
 * @version Dec.  4, 2011
 * @author  ASAMI, Tomoharu
 **/
class BookEntityDriver(val uri: String) extends G3EntityDriver {
  def this() = this("")

  def new_Agent(cmd: G3Command, ctx: G3AgentContext) = {
    QSymbol(cmd.uri) match {
      case KIND_BOOK => new BookEntityDriverAgent(uri, ctx)
      case KIND_AUTHOR => new AuthorEntityDriverAgent(uri, ctx)
      case KIND_PUBLISHER => new PublisherEntityDriverAgent(uri, ctx)
      case KIND_PUBLISH => new PublishEntityDriverAgent(uri, ctx)
    }
  }
}

/*
trait UseDataStore { // XXX
  val uri: String

  val context: G3AgentContext
  lazy val dsdriver = context.createDataStoreDriver(uri)
}
*/

class BookEntityDriverAgent(dsuri: String, context: G3AgentContext) extends G3DataStoreEntityDriverAgent(dsuri, context) {
  val entityName: QSymbol = KIND_BOOK
  val schema = Schema(
    IdField,
    ('name, XToken),
    ('author, XEntityReference(KIND_AUTHOR)),
    ('author_name, XToken, CDerivation('entityauthor, 'name, 'id, 'author)),
    ('publisher, XEntityReference(KIND_PUBLISHER)),
    ('publisher_name, XToken, CDerivation('entitypublisher, 'name, 'id, 'publisher))
  )
}

class AuthorEntityDriverAgent(dsuri: String, context: G3AgentContext) extends G3DataStoreEntityDriverAgent(dsuri, context) {
  val entityName: QSymbol = KIND_AUTHOR
  val schema = Schema(
    IdField,
    ('name, XToken),
    ('books, XEntityReference(KIND_BOOK), MZeroMore)
  )
}

class PublisherEntityDriverAgent(dsuri: String, context: G3AgentContext) extends G3DataStoreEntityDriverAgent(dsuri, context) {
  val entityName: QSymbol = KIND_PUBLISHER
  val schema = Schema(
    IdField,
    ('name, XToken),
    ('books, XEntityReference(KIND_BOOK), MZeroMore, CLinkQuery)
  )
}

class PublishEntityDriverAgent(dsuri: String, context: G3AgentContext) extends G3DataStoreEntityDriverAgent(dsuri, context) {
  val entityName: QSymbol = KIND_PUBLISH
  val schema = Schema(
    IdField,
    DateField,
    ('book, XEntityReference(KIND_BOOK)),
    ('book_name, XToken, CDerivation('entitybook, 'name, 'id, 'book)),
    ('author, XEntityReference(KIND_AUTHOR)),
    ('author_name, XToken, MZeroMore, CDerivation('entityauthors, 'name, 'id, 'author)),
    ('publisher, XEntityReference(KIND_PUBLISHER)),
    ('publisher_name, XToken, CDerivation('entitypublisher, 'name, 'id, 'publisher)),
    ('contributors, XEntityReference(KIND_AUTHOR), MZeroMore),
    ('contributor_names, XToken, MZeroMore, CDerivation('entityauthors, 'name, 'id, 'author))
  )
}

object BookEntitySpace {
  val KIND_BOOK = QSymbol('entitybook)
  val KIND_AUTHOR = QSymbol('entityauthor)
  val KIND_PUBLISHER = QSymbol('entitypublisher)
  val KIND_PUBLISH = QSymbol('entitypublish)
}
